package dinucleotides;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class Code implements Comparable<Code> {

	private List<String> listPaires;
	private int[] mots = { -1, -1, -1, -1, -1, -1 };
	private String affichage = null;
	private List<String> motsTraduit = null;

	public Code(int nbPaires, List<String> listPaires) {
		this.mots = new int[nbPaires];
		for (int i = 0; i < this.mots.length; i++) {
			this.mots[i] = -1;
		}
		this.listPaires = listPaires;
	}

	public Code(List<String> listPaires, int[] mots) {
		this.mots = (int[]) mots.clone();
		this.listPaires = listPaires;
	}

	public void rajouterPaire(int numPaire, int numMot) {
		this.mots[numPaire] = numMot;
		this.affichage = null;
		this.motsTraduit = null;

	}

	public List<String> getCodeTraduit() {
		if (this.motsTraduit == null) {
			this.motsTraduit = new ArrayList<String>();

			for (int i = 0; i < mots.length; i++) {
				if (mots[i] != -1) {
					this.motsTraduit.add(this.listPaires.get(2 * i + mots[i]));
				}
			}
		}
		return this.motsTraduit;
	}

	/* Transforme le code en String
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		if (this.affichage != null) {
			return this.affichage;
		}

		List<String> code = this.getCodeTraduit();
		Collections.sort(code);
		StringBuilder res = new StringBuilder();

		for (String s : code) {
			res.append(s + " ");
		}

		if (res.length() > 0) {
			res.deleteCharAt(res.length() - 1);
		}

		this.affichage = res.toString();
		return this.affichage;
	}

	/* Compare deux codes entre eux
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public boolean equals(Object o) {
		if (o instanceof Code) {
			return Arrays.equals(this.mots, ((Code) o).mots);
		}
		return false;
	}

	/* Permet de générer un code de hashage
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {
		final int init = 7;
		final int multiplier = 17;

		int result = init;
		for (int i = 0; i < this.mots.length; i++) {
			result = multiplier * result + this.mots[i];
		}

		return result;
	}
	
	/* Permet de comparer deux codes entre eux
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	@Override
	public int compareTo(Code c) {
		return this.toString().compareTo(c.toString());
	}
	
	public List<Code> getCodesSuivants() {
		List<Code> res = new ArrayList<Code>();

		for (int i = 0; i < this.mots.length; i++) {
			if (this.mots[i] == -1) {
				this.mots[i] = 0;
				res.add(new Code(listPaires, this.mots));
				this.mots[i] = 1;
				res.add(new Code(listPaires, this.mots));
				this.mots[i] = -1;
			}
		}
		return res;
	}
}